package com.example.my_gobang.game;

import com.example.my_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

/**
 * Creat with IntelliJ IDEA
 * Description:匹配器，实现匹配功能
 * User:WZW
 * Date:2022-08-22
 * Time:16:03
 */
@Component
public class Matcher {
    private Queue<User> normalQueue = new LinkedList<>();
    private Queue<User> highQueue = new LinkedList<>();
    private Queue<User> veryHighQueue = new LinkedList<>();
    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private RoomManager roomManager;

    // 操作匹配队列
    // 入队
    public void add(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.add(user);
                normalQueue.notify();
            }
            System.out.println("用户" + user.getUsername() + "进入normalQueue");
        } else if (user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.add(user);
                highQueue.notify();
            }
            System.out.println("用户" + user.getUsername() + "进入highQueue");
        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.add(user);
                veryHighQueue.notify();
            }
            System.out.println("用户" + user.getUsername() + "进入veryHighQueue");
        }
    }

    //出队
    public void remove(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.remove(user);
            }
        } else if (user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.remove(user);
            }
        } else
            synchronized (veryHighQueue) {
            veryHighQueue.remove(user);
            }
        System.out.println("用户" + user.getUsername() + "退出匹配队列");
    }

    public Matcher() {
        //创建三个线程，分别针对这三个匹配队列进行操作
        Thread t1 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    handlerMatch(normalQueue);
                }
            }
        };
        t1.start();
        Thread t2 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    handlerMatch(highQueue);
                }
            }
        };
        t2.start();
        Thread t3 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    handlerMatch(veryHighQueue);
                }
            }
        };
        t3.start();
    }

    private void handlerMatch(Queue<User> matchQueue) {
        synchronized (matchQueue) {
            try {
//                if (matchQueue.size() < 2) {
//                    return;
                while (matchQueue.size() < 2) {
                    matchQueue.wait();
                }
                // 尝试从队列中取出两个玩家
                User p1 = matchQueue.poll();
                User p2 = matchQueue.poll();
                System.out.println("匹配出两个玩家：" + p1.getUsername() + ", " + p2.getUsername());
                // 获取玩家的websocket会话，告诉玩家匹配到了对手
                WebSocketSession session1 = onlineUserManager.getFromGameHall(p1.getUserid());
                WebSocketSession session2 = onlineUserManager.getFromGameHall(p2.getUserid());
                //进行双重校验
                if (session1 == null) {
                    // 把玩家2重新放回匹配队列中
                    matchQueue.offer(p2);
                    return;
                }
                if (session2 == null) {
                    matchQueue.offer(p1);
                    return;
                }
                if (session1 == session2) {
                    // 把其中一个玩家放入匹配队列
                    matchQueue.offer(p1);
                    return;
                }
                // TODO 把匹配的玩家放到一个游戏房间中
                Room room = new Room();
                roomManager.add(room, p1.getUserid(), p2.getUserid());

                // 反馈匹配信息给玩家
                System.out.println("反馈匹配信息给玩家");
                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchSuccess");
                session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response1)));
                System.out.println("反馈匹配信息给玩家1");
                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchSuccess");
                session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));

                System.out.println("反馈匹配信息给玩家2");
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
